CGIs and WebSTAR
Volume Number: 11
Issue Number: 7
Column Tag: Internet Development
CGI Applications and WebSTAR 
Have some fun with your World Wide Web server.
By Jon Wiederspan, jonwd@first.com
Note: Source code files accompanying article are located on MacTech CD-ROM orsource code disks.
[The World Wide Web is changing rapidly and announcements of new companies,
mergers, licensing agreements, and new WWW software are arriving with increasing
frequency. In light of this, there is a high probability that anything printed about the
Web is out of date by the time you read it. Even as we printed our previous article
introducing MacHTTP, it was being licensed to StarNine Technologies, Inc. and
relabeled WebSTAR. More information on this is available at
“http://www.starnine.com/”.
WebSTAR is now available in several flavors depending on your budget and needs.
Every WebSTAR version, though, uses the same interface to CGI applications that was
originally part of MacHTTP. So, whether you are using WebSTAR Pro or still hanging
on to your MacHTTP 2.0.1 server, the code introduced in this article will work for
you.
Welcome to the Web.
- Ed nst, editorial@xplain.com]
In my previous article (May 1995), I introduced you to WebSTAR (formerly
MacHTTP), a software package that will turn your Macintosh into a World Wide Web
server. WebSTAR is the perfect solution for anyone that wants to put documents and
other information on the WWW, but if you’re like me, that’s not enough. You can see
all those other sites with cool maps and forms and you want the same. Actually, you
want better! Well, I’m here to show you how easy it is to add these functions to your
WebSTAR site using AppleScript and a few items you probably have in your kitchen,
like chocolate.
This article is intended for those who already have some programming or
AppleScript background. It is not intended as a complete introduction to AppleScript.
Judging by the mail I have already received about these scripts, it doesn’t take much
experience at all and even some complete novices have successfully used them, but you
shouldn’t expect miracles (at least not here). These lessons will make things easier
for most people, but they still require work and study. Take your time, think about
what is said here, challenge anything that seems to be wrong (its not inconceivable that
I get something wrong here) and do things in order as much as possible.
What does CGI mean?
CGI stands for “Common Gateway Interface”. There. Now you know. The CGI definition
provides a standard for external gateway applications to interface with information
servers such as WebSTAR. These gateway applications are used to provide new
features to a WWW site either by acting as a gateway to another application on the
server (such as searching a database or creating charts in a spreadsheet) or by
processing the data themselves (such as a map).
The CGI standard controls what kind of information is passed from the
information server to the external gateway application and how the information is
formatted. It does not control how the information is passed, though. That is left up to
each server to implement in the best way possible for that system. WebSTAR uses
Apple events to communicate with CGI applications. This means that you can write
your CGI application in any language that can handle Apple events, which includes not
only all of the major languages (C, Pascal, LISP, SmallTalk, Fortran), but also
scripting languages like AppleScript, Frontier, and MacPerl, and even applications
with scripting languages that qualify such as HyperCard and 4D.
Although AppleScript CGI applications are not the fastest, this is what I’ll be
showing you because they are the easiest to understand. AppleScript relieves you from
almost all of the tedium of making an interface, initializing various things, and
registering Apple events. It is also a language that somewhat resembles the English
language, unlike C which most closely resembles a bowl of alphabet soup.
How CGI Applications Work - The Basics
When trying to understand how CGI applications work, the first thing to learn is the
difference between the server and the client. WebSTAR is the server. Mosaic,
MacWeb, and Netscape are all clients. The client software is smart. It knows how to
interpret HTML, how to handle partial URL’s and URL’s with strange extra information
like search strings, and how to find servers. The server software is stupid. It does
fine as long as it is fed the right information, but if a client sends bad information, the
server has no idea what to do. Therefore, in most transactions it is the client that’s
doing all the cool stuff and the server is just passing back a file or an error code.
Figure 1. Client-Server interaction in HTTP
First, let’s look at a typical client-server transaction on the Web. Here’s an
example of the interaction that might occur when the user wants an HTML page:
Netscape: My user clicked on a link to URL
http://www.uwtc.washington.edu/UWHome.html. I’ll send a request for the
document /UWHome.html to machine www.uwtc.washington.edu using HTTP.
WebSTAR: Ah! So you want one of my pages. Here is all the data from the URL you
sent. I’m sending it as a text/html MIME type.
Netscape: Here it comes. The MIME type is text/html. I’ll interpret this as an
HTML document then and display it correctly for my user.
WebSTAR: I couldn’t care less how you display it. I’m done dumping the data so
goodbye.
This example is extremely simplified and ignores a lot of the communications
that occur with HTTP, but it does show you that the client is responsible for properly
placing the request to the correct server. All the server does is try to find the file and
return it or return an error code. Once the server is done returning the file, it
completely forgets that the client was ever there.
When the user requests a URL that involves a CGI application (like clicking on a
map or submitting a form) things become a little more complicated. There is not only
interaction between the client and server, but also between the server and the CGI
application. Let’s take a look now at the conversation that might occur between a
client, server, and CGI when handling a map click (assuming they speak English, of
course).
User: Hmmmm. A map of Washington state. There’s a star in the upper right-hand
corner. I wonder what that’s for. I think I’ll click on it.
Netscape: Let’s see, that click was at 287,48. I’ll add that to the URL that was
given with the map and send it to the server.
WebSTAR: Hey, someone sent me a URL with some extra data. That URL is for a CGI
application on this machine. Well, I’ll just send an Apple event to that CGI
application with the extra data enclosed. I’m glad I don’t have to do anything to
the data myself.
CGI app: Finally, an Apple event! Let’s see, first I decode the extra data that was
sent. Now I can use these map click coordinates to figure out what page to return
to the client. Here it is - I’ll send the server an Apple event reply, containing
the URL for the new page and an HTTP header with the code to redirect the client
to that page.
WebSTAR: Finally. I’ve been waiting for this Apple event reply. I’ll just
repackage this and send it back to the client. I sure hope the CGI application
remembered to include a proper HTTP header. I don’t check that sort of thing
myself.
Netscape: Hmmm. This code tells me that I should get this other URL instead of the
one I originally requested. I’ll send a request to the server for this other page.
WebSTAR: Another request for one of my pages. Here’s the file contents as
text/html.
Netscape: Here comes another HTML page. Better display it nicely for my user.
User: Republic, Washington? I’ve never even heard of that place before!
Well, that was a bit long, but it should give you an idea of the complex
interactions that go on when you are using a CGI application. The server still isn’t
being very bright. As you saw, the server didn’t really do any processing of the data
that was passed to it. It just acted as a liaison between the client and the CGI
application, blindly passing whatever those two wanted to send to each other. For more
information, see the interactions in Figure 2.
Figure 2. Complex interactions between client, server, and CG 1.
Client-Server interaction in HTTP
How CGI Applications Really Work - The Less Basics
Now that you have an idea of where all of the information is going and who’s passing it
where, it is time to cover some of the more technical points.
Apple events and CGIs
• WebSTAR uses the name extension of a file to determine whether it is a CGI
application or not. Any file which ends in “.cgi” or “.acgi” will be treated as a
CGI application, whether it actually is one or not. CGI applications can exist
anywhere in the WebSTAR directory structure so be certain never to use that
extension for a file unless you are certain it can handle the CGI Apple event.
• The Apple event used by WebSTAR to send information to CGI applications is
“WWWΩsdoc”. There is another event that WebSTAR supports which is often
referred to as the “search event” (WWWΩsrch). This is a remnant from the days
before CGI support and there is no guarantee that support for it will remain in
future versions so avoid using it.
• There are two methods for sending information to CGI applications, the GET and
POST methods. The two serve very similar functions but the POST method has the
advantage because it can send more information to the server (24K for POST
method vs. 2K for GET method). Because of that I will cover only the POST
method. If you feel a need to use GET at some time, it is very easy to convert the
code.
• There are two ways to run a CGI application; synchronously and
asynchronously. When run synchronously, WebSTAR waits for information to
return from the CGI. This makes most CGI applications run faster, but it also
ties up your entire server while the CGI is running. When you run
asynchronously, the server doesn’t wait for the CGI application but instead goes
on processing connections. This steals processing time so the CGI application will
run more slowly, but you won’t have connections piling up. Once again,
WebSTAR uses the name extension to tell which method you want used. Any file
ending in “.cgi” is run synchronously and any ending in “.acgi” is run
asynchronously. It is a little more complex to write an asynchronous CGI
application (ACGI) because there is the possibility that while the ACGI is
running, WebSTAR will send it another event. These events queue up, waiting for
the previous event to finish processing. You need to be certain to leave some code
that will pause after finishing one event so the ACGI has time to check whether
there is another event queued up. Because of this, any ACGI can also run as a CGI,
but the reverse is not always true. All of the code provided here can be used to
create both CGI and ACGI applications without modification.
• WebSTAR does not do any processing of the actual data going to the CGI application
or of pages being returned by the CGI application to the client. The only things
WebSTAR does is package the data in an Apple event (to go to the CGI) and remove
it from the Apple event reply (to return to the client). Therefore, any errors
that occur are almost always the fault of either the CGI application or the client.
Return Codes
When WebSTAR sends an Apple event to a CGI application, it waits for an Apple
event Reply in return. As I noted above, WebSTAR doesn’t do any processing itself.
Therefore, the Apple event Reply returned by the CGI application must contain
instructions for WebSTAR on what to tell the client. There are two things the CGI must
send back: an HTTP header and some data. The header tells the client what happened
(success, error) and what to do with the data that is being returned. The data can be a
block of text, an HTML document, or the URL for a file. To indicate what the client
should do with the data, the header contains a special Return Code. These codes are part
of the HTTP standard and there are many of them. Typically, though, there are only
two that your CGI application should return, “200 OK” or “302 FOUND”. “200 OK” is
used to tell the client that the data being returned is a file and the client should try to
display it. The “302 FOUND” code tells the client that the data is a URL and the client
will then try to connect to that URL. This “302 FOUND” code is also called “URL
Redirection”, because it redirects the client to a different URL.
In this lesson I will be using the “200 OK” code in the header and returning a
block of HTML text. At the end of the lesson, I will also include some sample code with
a “302 FOUND” header to show how that works a little differently.
The Basic CGI Application
Now you’re ready to dig into some code. This month we are going to make the “Hello,
world.” equivalent for CGI applications. It won’t do anything very exciting, but it will
be a CGI application. When run, this CGI application will return an HTML page listing
all of the data passed to it by WebSTAR. This will be very useful later when you’re
debugging your other CGI applications.
With this lesson you will learn:
• how to accept the Apple event information from WebSTAR when the POST method
is used,
• what information is passed from WebSTAR to the CGI application
• how to build an HTTP header and an HTML page to return to WebSTAR
• how to return the header and page to WebSTAR
This code is written in AppleScript. If you have System 7.5, you probably got
AppleScript free on your system installation disks. If not, you will need to purchase
AppleScript from APDA or find an AppleScript book that includes the ScriptEditor on
disk. The latter is preferable, since you will need an AppleScript book in order to
create your own CGI applications after you are through here.
The AppleScript Code
Here is the entire code of this lesson. A text file of the code is available at the usual
online sources and on the monthly disk.
Listing 1: BasicCGI.txt
property crlf : (ASCII character 13) & (ASCII character 10)
property http_10_header : "HTTP/1.0 200 OK" & crlf
& "Server: WebSTAR/1.0 ID/ACGI" & crlf
& "MIME-Version: 1.0" & crlf & "Content-type: text/html"
& crlf & crlf
on event WWWΩsdoc path_args
given class kfor:http_search_args, class post:post_args,
class meth:method, class addr:client_address,
class user:username, class pass:password,
class frmu:from_user, class svnm:server_name,
class svpt:server_port, class scnm:script_name,
class ctyp:content_type, class refr:referer,
class Agnt:user_agent, class Kact:action,
class Kapt:action_path, class Kcip:client_ip,
class Kfrq:full_request
set return_page to http_10_header
& "Unprocessed Results"
& "Unprocessed Results
" & return
& "path_args
" & return & path_args & return
& "http_search_args
" & return & http_search_args
set return_page to return_page & return
& "post_args
" & return & post_args & return
& "method
" & return & method & return
& "client_address
" & return & client_address
& return
& "username
" & return & username & return